package com.tebiecloud.base.server.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tebiecloud.base.client.constants.BaseConstants;
import com.tebiecloud.base.client.model.UserAccount;
import com.tebiecloud.base.client.model.entity.BaseAccount;
import com.tebiecloud.base.client.model.entity.BaseAccountLogs;
import com.tebiecloud.base.client.model.entity.BaseRole;
import com.tebiecloud.base.client.model.entity.BaseUser;
import com.tebiecloud.base.server.mapper.BaseUserMapper;
import com.tebiecloud.base.server.service.*;
import com.tebiecloud.base.server.service.feign.MpminiAccountRefServiceClient;
import com.tebiecloud.common.constants.ResultEnum;
import com.tebiecloud.common.model.ResultBody;
import com.tebiecloud.common.mybatis.base.service.impl.BaseServiceImpl;
import com.tebiecloud.common.security.SecurityAuthority;
import com.tebiecloud.common.security.SecurityConstants;
import com.tebiecloud.common.utils.StringUtils;
import com.tebiecloud.common.utils.WebUtils;
import com.tebiecloud.mpweixin.client.model.entity.MpminiAccountRef;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 系统用户-管理员信息 服务实现类
 * @author tebie
 * @date 2019-08-01
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class BaseUserServiceImpl extends BaseServiceImpl<BaseUserMapper, BaseUser> implements BaseUserService {

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private BaseUserMapper baseUserMapper;

    @Autowired
    private BaseRoleService baseRoleService;

    @Autowired
    private BaseAuthorityService baseAuthorityService;

    @Autowired
    private BaseAccountService baseAccountService;

    @Autowired
    private BaseAccountLogsService baseAccountLogsService;

    @Autowired
    private MpminiAccountRefServiceClient mpminiAccountRefServiceClient;

    /**
     * 获取用户登录账号信息
     * @param userId
     * @return
     */
    @Override
    public UserAccount getUserAccount(Long userId) {
        // 用户权限列表
        List<SecurityAuthority> authorities = Lists.newArrayList();
        // 用户角色列表
        List<Map> roles = Lists.newArrayList();
        List<BaseRole> rolesList = baseRoleService.getBaseRoleList(userId);
        if (rolesList != null) {
            for (BaseRole role : rolesList) {
                Map roleMap = Maps.newHashMap();
                roleMap.put("roleId", role.getRoleId());
                roleMap.put("roleCode", role.getRoleCode());
                roleMap.put("roleName", role.getRoleName());
                // 用户角色详情
                roles.add(roleMap);
                // 加入角色标识
                SecurityAuthority authority = new SecurityAuthority(role.getRoleId().toString(), SecurityConstants.AUTHORITY_PREFIX_ROLE + role.getRoleCode(), null, "role");
                authorities.add(authority);
            }
        }

        //查询系统用户资料
        BaseUser baseUser = baseUserMapper.selectById(userId);

        // 加入用户权限
//        List<SecurityAuthority> userGrantedAuthority = baseAuthorityService.getSecurityAuthorityList(userId, CommonConstants.ROOT.equals(baseUser.getUserName()));
        List<SecurityAuthority> userGrantedAuthority = baseAuthorityService.getSecurityAuthorityList(userId, true);
        if (userGrantedAuthority != null && userGrantedAuthority.size() > 0) {
            authorities.addAll(userGrantedAuthority);
        }
        UserAccount userAccount = new UserAccount();
        // 昵称
        userAccount.setNickName(baseUser.getNickName());
        // 头像
        userAccount.setAvatar(baseUser.getAvatar());
        // 权限信息
        userAccount.setAuthorities(authorities);
        userAccount.setRoles(roles);
        return userAccount;
    }

    /**
     * 获取用户登录账号信息
     * 支持密码、手机号、email登陆
     * 其他方式没有规则，无法自动识别。需要单独开发
     * @param account
     * @return
     */
    @Override
    public UserAccount getUserAccountForLogin(String account, String password, String type) {
        if (StringUtils.isBlank(account)) {
            return null;
        }
        // 第三方登录标识
        String loginType = type;
        BaseAccount baseAccount = null;
        log.info("xiaoc>> 登录类型：{}", loginType);
        if (StringUtils.isNotBlank(loginType)) {
            if(BaseConstants.ACCOUNT_TYPE_MP.equalsIgnoreCase(loginType)) { // 公众号登录
                baseAccount = baseAccountService.getAccount(account, loginType, BaseConstants.ACCOUNT_DOMAIN_MP);
                if(baseAccount != null) {
                    baseAccount.setPassword(passwordEncoder.encode(password));
                }
            } else if(BaseConstants.ACCOUNT_TYPE_MINIPROGRAM.equalsIgnoreCase(loginType)) { // 小程序登录
                baseAccount = baseAccountService.getAccount(account, loginType, BaseConstants.ACCOUNT_DOMAIN_MPMINI);
                if(baseAccount != null) {
                    baseAccount.setPassword(passwordEncoder.encode(password));
                }
            } else if(BaseConstants.ACCOUNT_TYPE_STAFF_PHONE.equalsIgnoreCase(loginType)) { // 员工手机号登录
                baseAccount = baseAccountService.getAccount(account, loginType, BaseConstants.ACCOUNT_DOMAIN_USER);
                if(baseAccount != null) {
                    baseAccount.setPassword(passwordEncoder.encode(password));
                }
            } else if(BaseConstants.ACCOUNT_TYPE_STORE_ACCOUNT.equalsIgnoreCase(loginType)) { // 门店登录
                baseAccount = baseAccountService.getAccount(account, BaseConstants.ACCOUNT_TYPE_STORE_ACCOUNT, BaseConstants.ACCOUNT_DOMAIN_USER);
                if(baseAccount == null) {
                    baseAccount = baseAccountService.getAccount(account, BaseConstants.ACCOUNT_TYPE_AGM, BaseConstants.ACCOUNT_DOMAIN_USER);
                }
            } else if(BaseConstants.ACCOUNT_TYPE_SYSTEM_AUTO.equalsIgnoreCase(loginType)) { // 系统自动登录
                log.info("xiaoc>> 系统自动登录");
                baseAccount = baseAccountService.getAccount(account, null, null);
                if(baseAccount != null) {
                    baseAccount.setPassword(passwordEncoder.encode(password));
                }
            } else {
                baseAccount = baseAccountService.getAccount(account, loginType, BaseConstants.ACCOUNT_DOMAIN_ADMIN);
            }
        } else { // 非第三方登录
//            if (StringUtils.matchMobile(account)) { // 手机号登陆
//                baseAccount = baseAccountService.getAccount(account, BaseConstants.ACCOUNT_TYPE_MOBILE, BaseConstants.ACCOUNT_DOMAIN_ADMIN);
//            } else if (StringUtils.matchEmail(account)) { // 邮箱登陆
//                baseAccount = baseAccountService.getAccount(account, BaseConstants.ACCOUNT_TYPE_EMAIL, BaseConstants.ACCOUNT_DOMAIN_ADMIN);
//            } else { // 用户名登录
                baseAccount = baseAccountService.getAccount(account, BaseConstants.ACCOUNT_TYPE_USERNAME, BaseConstants.ACCOUNT_DOMAIN_ADMIN);
//            }
        }

        // 获取用户详细信息
        if (baseAccount != null) {
            //添加登录日志
            try {
                HttpServletRequest request = WebUtils.getHttpServletRequest();
                if (request != null) {
                    BaseAccountLogs log = new BaseAccountLogs();
                    log.setDomain(baseAccount.getDomain());
                    log.setUserId(baseAccount.getUserId());
                    log.setAccount(baseAccount.getAccount());
                    log.setAccountId(baseAccount.getAccountId());
                    log.setAccountType(baseAccount.getAccountType());
                    log.setLoginIp(WebUtils.getRemoteAddress(request));
                    log.setLoginAgent(request.getHeader(HttpHeaders.USER_AGENT));
                    baseAccountLogsService.save(log);
                }
            } catch (Exception e) {
                log.error("添加登录日志失败:{}", e);
            }
            // 用户权限信息
            UserAccount userAccount = getUserAccount(baseAccount.getUserId());
            // 复制账号信息
            BeanUtils.copyProperties(baseAccount, userAccount);
            return userAccount;
        }
        return null;
    }

}
